package com.woniuxy.qiantai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.qiantai.entity.Cartitem;
import com.woniuxy.qiantai.entity.Product;
import com.woniuxy.qiantai.entity.Shop;
import com.woniuxy.qiantai.mapper.CartitemMapper;
import com.woniuxy.qiantai.mapper.ProductMapper;
import com.woniuxy.qiantai.mapper.ShopMapper;
import com.woniuxy.qiantai.service.CartitemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.qiantai.vo.OrderPreview;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author firstGroup
 * @since 2023-02-22 09:45:58
 */
@Service
public class CartitemServiceImpl extends ServiceImpl<CartitemMapper, Cartitem> implements CartitemService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    RedisTemplate<String, Object> stringObjectRedisTemplate;

    @Override
    public void addToCart(Integer userId, Integer productId) {
        //根据商品id查询出商品的对象
        Product product = productMapper.selectById(productId);
        //使用自定义RedisTemplate 操作数据 定义用户的id为key 商品的id为hashkey 购物车为value
        HashOperations<String, Object, Object> hashOperations = stringObjectRedisTemplate.opsForHash();
        //根据key和hashkey 查询出购物车对象
        Object o = hashOperations.get(String.valueOf(userId), String.valueOf(productId));
        if (Objects.isNull(o)) {
            //根据商品的shop_id 查询出店铺的对象
            Shop shop = shopMapper.selectById(product.getShopId());
            //如果查询结果为null  表明是第一次存储购物车数据到Redis中
            Cartitem cartitem = new Cartitem();
            //cartitem.setId(hashOperations.values(String.valueOf(userId)).size()+1);
            cartitem.setModifyTime(new Date());
            cartitem.setUserId(userId);
            cartitem.setCount(new BigDecimal(1));
            cartitem.setProductName(product.getName());
            cartitem.setProductPrice(product.getPrice());
            cartitem.setProductId(productId);
            cartitem.setSumPrice(product.getPrice());
            cartitem.setShopName(shop.getName());
            cartitem.setShopId(shop.getId());
            cartitem.setShopImgSrc(shop.getImgSrc());
            System.out.println("商品："+product);
            cartitem.setProductImgSrc(product.getImgSrc());
            //存入数据
            hashOperations.put(String.valueOf(userId), String.valueOf(productId), cartitem);

        } else {
            Cartitem cartitem = (Cartitem) o;
            cartitem.setModifyTime(new Date());
            cartitem.setCount(cartitem.getCount().add(new BigDecimal(1)));
            cartitem.setSumPrice(cartitem.getSumPrice().add(product.getPrice()));
            //覆盖之气的购物车数据
            hashOperations.put(String.valueOf(userId), String.valueOf(productId), cartitem);
        }
    }

    @Override
    public Page<Cartitem> selectPage(Integer userId, Integer pageSize, Integer currentPage) {
        Page<Cartitem> cartitemPage = new Page<>(currentPage, pageSize);
        HashOperations<String, Object, Cartitem> hashOperations = stringObjectRedisTemplate.opsForHash();
        List<Cartitem> cartitems = hashOperations.values(String.valueOf(userId));
        cartitems.sort(new Comparator<Cartitem>() {
            @Override
            public int compare(Cartitem o1, Cartitem o2) {
                return (int) o2.getModifyTime().getTime() - (int) o1.getModifyTime().getTime();
            }
        });

        int totalPages = cartitems.size() % pageSize == 0 ? (cartitems.size() / pageSize) : (cartitems.size() / pageSize + 1);
        List<Cartitem> targetList = new ArrayList<>();
        for (int i = (currentPage - 1) * pageSize; i < (currentPage - 1) * pageSize + pageSize && i < cartitems.size(); i++) {
            targetList.add(cartitems.get(i));
        }
        cartitemPage.setPages(totalPages);
        cartitemPage.setRecords(targetList);
        cartitemPage.setTotal(cartitems.size());
        return cartitemPage;
    }

    @Override
    public BigDecimal calculateTotalPrice(Integer[] productIds, Integer userId) {
        HashOperations<String, Object, Object> hashOperations = stringObjectRedisTemplate.opsForHash();
        BigDecimal totalPrice = new BigDecimal("0.00");
        for (Integer productId : productIds) {
            Cartitem cartitem = (Cartitem) hashOperations.get(String.valueOf(userId), String.valueOf(productId));
            totalPrice = totalPrice.add(cartitem.getSumPrice());
        }
        return totalPrice;
    }

    @Override
    public void updateCount(Integer productId, Integer userId, Integer count) {
        HashOperations<String, Object, Object> hashOperations = stringObjectRedisTemplate.opsForHash();
        //根据key和 hashkey  从Redis中读取到对应的购物车信息
        Cartitem cartitem = (Cartitem) hashOperations.get(String.valueOf(userId), String.valueOf(productId));

        if (Objects.isNull(cartitem)) {
            System.out.println("购物车没有该商品");
            return;
        }
        //根据商品id查询出商品对象信息
        Product product = productMapper.selectById(productId);
        if (count == 0) {
            //删除对应的商品信息
            hashOperations.delete(String.valueOf(userId), String.valueOf(productId));

        } else {
            cartitem.setCount(new BigDecimal(count));
            cartitem.setSumPrice(cartitem.getCount().multiply(cartitem.getProductPrice()));
            //重新存入Redis
            hashOperations.put(String.valueOf(userId), String.valueOf(productId), cartitem);

        }
    }

    @Override
    public void updateCartItemCount(Integer productId, Integer userId, Integer command) {
        HashOperations<String, Object, Object> hashOperations = stringObjectRedisTemplate.opsForHash();
        //根据key和 hashkey  从Redis中读取到对应的商品信息
        Cartitem cartitem = (Cartitem) hashOperations.get(String.valueOf(userId), String.valueOf(productId));

        if (Objects.isNull(cartitem)) {
            System.out.println("购物车没有该商品");
            return;
        }
        //根据商品id查询出商品对象信息
        Product product = productMapper.selectById(productId);
        if (command == -1) {
            //对购物车商品数量-1
            if (Objects.equals(String.valueOf(cartitem.getCount()), String.valueOf(1))) {
                //如果购物车该商品就剩下一件  需要执行删除操作
                hashOperations.delete(String.valueOf(userId), String.valueOf(productId));
                System.out.println("清除" + product.getName());
            } else {
                //如果商品数量不等于1 对购物车商品数量-1
                cartitem.setModifyTime(new Date());
                cartitem.setCount(cartitem.getCount().subtract(new BigDecimal(1)));
                cartitem.setSumPrice(cartitem.getSumPrice().subtract(product.getPrice()));
                //重新存入Redis
                hashOperations.put(String.valueOf(userId), String.valueOf(productId), cartitem);
                System.out.println("减少" + product.getName());
            }
        } else if (command == 1) {
            //对购物车商品数量+1
            cartitem.setModifyTime(new Date());
            cartitem.setCount(cartitem.getCount().add(new BigDecimal(1)));
            cartitem.setSumPrice(cartitem.getSumPrice().add(product.getPrice()));
            //重新存入Redis
            hashOperations.put(String.valueOf(userId), String.valueOf(productId), cartitem);
            System.out.println("增加" + product.getName());
        } else if (command == 0) {
            //删除对应的商品信息
            hashOperations.delete(String.valueOf(userId), String.valueOf(productId));
            System.out.println("清除" + product.getName());

        }
    }

    @Override
    public OrderPreview createOrderPreview(Integer[] productIds, Integer userId) {
        BigDecimal totalPrice = calculateTotalPrice(productIds, userId);
        OrderPreview orderPreview = new OrderPreview();
        List<Cartitem> cartitemList = new ArrayList<>();
        HashOperations<String, Object, Cartitem> hashOperations = stringObjectRedisTemplate.opsForHash();
        for (Integer productId : productIds) {
            Cartitem cartitem = hashOperations.get(String.valueOf(userId), String.valueOf(productId));
            cartitemList.add(cartitem);
        }
        orderPreview.setTotalPrice(totalPrice);
        orderPreview.setCartitemList(cartitemList);
        return orderPreview;
    }


}
